/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.farmcode.api.util;

import com.farmcode.api.plugin.AuthenticationPlugin;
import com.farmcode.api.plugin.ConfigureException;
import com.farmcode.api.plugin.ObjectInfoPlugin;
import com.farmcode.api.plugin.Plugin;
import com.farmcode.api.plugin.PluginNotFountException;
import com.farmcode.api.plugin.objectinfo.ObjectInfoPluginManager;
import com.farmcode.api.plugin.objectinfo.PluginNotFoundException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.InitialContext;
import javax.naming.NamingException;

/**
 *
 * @author oiprado
 */
public class FARMCodeAPI {

    public static final String PARSER = "com.farmcode.core.runtime.parser";
    public static final String DATABASE_ENGINE = "com.farmcode.core.runtime.database";
    private static Properties properties = null;

    private static InitialContext getContext(String name) throws NamingException, IOException {
        return new InitialContext(getProperties(name));
    }

    public static<T> T getInstance(String ejbName)  throws NamingException, IOException{
        return (T)getContext(ejbName).lookup(properties.getProperty("com.farmcode.api.ejb.name"));
    }
    
   public static Properties getProperties(String name) throws IOException {
            properties = new Properties();
            final ClassLoader cl = Thread.currentThread().getContextClassLoader();
            final InputStream inStream = cl.getResourceAsStream(name + ".properties");
            if (inStream != null) {
                try {
                    properties.load(inStream);
                } finally {
                    inStream.close();
                }
            }
        return properties;
    }
    
    public static Properties getPluginContext(String plugin) throws IOException{
        Properties context = com.farmcode.server.config.InitialContext.configure();
        String home = context.getProperty("com.farmcode.server.path.home");
        String pluginPath = home + File.separatorChar + context.getProperty("com.farmcode.server.path.plugins");
        return getProperties(new File(pluginPath + File.separatorChar+ plugin + ".properties"));
    }
    
    private static Plugin getPluginInstance(String plugin) throws PluginNotFountException, IOException{        
        try {
            Properties context = com.farmcode.server.config.InitialContext.configure();
            return (Plugin)Class.forName(context.getProperty(plugin)).newInstance();
        } catch (Exception ex) {
            throw new PluginNotFountException(ex);
        }
    }
    
    public static AuthenticationPlugin getAuthenticationPlugin() throws IOException, ConfigureException, PluginNotFountException{
        AuthenticationPlugin authenticationPlugin;
        authenticationPlugin = (AuthenticationPlugin)getPluginInstance(Plugin.AUTHENTICATION);
        authenticationPlugin.configure();
        return authenticationPlugin;
    }
    
    public static ObjectInfoPlugin getObjectInfoPlugin(String name, String type) throws PluginNotFoundException, IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, ConfigureException{
        Properties context = com.farmcode.server.config.InitialContext.configure();
        ObjectInfoPlugin objectInfoPlugin = null;
        ObjectInfoPluginManager pluginManager = null;
        String path = 
                (
                    context.getProperty("com.farmcode.server.home")    
                    + 
                    File.separator                                                              
                    + 
                    context.getProperty("com.farmcode.server.path.plugins")  
                    + 
                    File.separator                                                             
                    +
                    context.getProperty("com.farmcode.api.plugin.objectinfo.config")
                );
        File plugins = new File(path);
        Properties config = FARMCodeAPI.getProperties(plugins);
        
        for (Object key : config.keySet()) {
            String castKey = (String)key;
            if(config.getProperty(castKey) .equals(type)){
               pluginManager = (ObjectInfoPluginManager)Class.forName(config.getProperty((String)key)).newInstance();
               break;
            }
        }
        
        objectInfoPlugin = pluginManager.getPlugin(name);
        
        objectInfoPlugin.configure();
        return objectInfoPlugin;
    }
    
    public static List<ObjectInfoPluginManager> getObjectInfoPlugins() throws PluginNotFoundException, IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, ConfigureException{
        Properties context = com.farmcode.server.config.InitialContext.configure();
        List<ObjectInfoPluginManager> plugins = new ArrayList<ObjectInfoPluginManager>();
        
        String path = 
                (
                    context.getProperty("com.farmcode.server.home")    
                    + 
                    File.separator                                                              
                    + 
                    context.getProperty("com.farmcode.server.path.plugins")  
                    + 
                    File.separator                                                             
                    +
                    context.getProperty("com.farmcode.api.plugin.objectinfo.config")
                );
        File file = new File(path);
        Properties config = FARMCodeAPI.getProperties(file);
        
       for (Object key : config.keySet()) {
               ObjectInfoPluginManager manager = (ObjectInfoPluginManager)Class.forName(config.getProperty((String)key)).newInstance();
               plugins.add(manager);
        }
        return plugins;
    }    
    
    public static Properties getProperties(File file) throws IOException {
        Properties props = new Properties();
        if(file != null){
            FileInputStream fis = new FileInputStream(file);
            props.load(fis);
            fis.close();
        }
        return props;
    }
}
